package ifile

import (
	"context"
	"encoding/base64"
	"gitee.com/bobo-rs/idea-space-framework/pkg/img"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/gfile"
	"os"
)

// FileAttract 文件属性
type FileAttract struct {
	Path string
	Ctx  context.Context
}

// FileInfo 文件详情
type FileInfo struct {
	Size   int64  // 内存大小
	Width  int    // 宽度
	Height int    // 高度
	Name   string // 文件名
	Hash   string // hash值
}

// New 实例
func New(path string) *FileAttract {
	return &FileAttract{
		Path: path,
	}
}

// Open 打开文件内容
func (a *FileAttract) Open() (*os.File, error) {
	return os.Open(a.Path)
}

// Content 读取文件二进制内容
func (a *FileAttract) Content() ([]byte, error) {
	// 打开文件
	file, err := a.Open()
	if err != nil {
		return nil, gerror.Wrapf(err, `打开File失败%s`, err.Error())
	}
	defer func() {
		_ = file.Close()
	}()

	// 转换成byte
	return ReadContent(file)
}

// MustContentString 读取文件内容转字符串
func (a *FileAttract) MustContentString() string {
	buffer, err := a.Content()
	if err != nil {
		return ""
	}
	return string(buffer)
}

// MustContentBase64String 读取文件内容转换Base64字符
func (a *FileAttract) MustContentBase64String() string {
	buffer := a.MustContentString()
	if len(buffer) == 0 {
		return ""
	}
	return base64.StdEncoding.EncodeToString([]byte(buffer))
}

// Hasher 读取文件Hash值
func (a *FileAttract) Hasher() (string, error) {
	// 打开文件
	f, err := a.Open()
	if err != nil {
		return "", gerror.Wrapf(err, `打开File失败%s`, err.Error())
	}

	// 关闭文件
	defer func() {
		_ = f.Close()
	}()

	// 读取hash内容byte并转换为十六进制
	return ReadHasher(f)
}

// MustHasherString 必须创建获取Hash值
func (a *FileAttract) MustHasherString() string {
	hasher, err := a.Hasher()
	if err != nil {
		return ""
	}
	return hasher
}

// Attract 获取文件详情属性
func (a *FileAttract) Attract() (*FileInfo, error) {

	// 打开文件
	f, err := a.Open()
	if err != nil {
		return nil, gerror.Wrapf(err, `打开File失败%s`, err.Error())
	}

	// 关闭文件
	defer func() {
		_ = f.Close()
	}()

	// 读取文件详情
	fs, err := f.Stat()
	if err != nil {
		return nil, gerror.Wrapf(err, `获取File详情失败%s`, err.Error())
	}
	// 初始化
	item := &FileInfo{
		Name: fs.Name(),
		Size: fs.Size(),
	}

	// 图片类获取尺寸
	if img.IsValidImageExt(gfile.ExtName(a.Path)) {
		item.Width, item.Height, err = ReadImageWH(f)
		if err != nil {
			return nil, err
		}
	}

	// 获取文件hash值
	item.Hash, err = ReadHasher(f)
	if err != nil {
		return nil, err
	}

	return item, nil
}
